package main

import (
	"flag"
	"fmt"
	"io"
	"net"
	"os"
	"strings"
)

type Client struct {
	Ip   string
	Port int
	Name string
	conn net.Conn
	flag int
}

func NewClient(ip string, port int) *Client {
	client := &Client{
		Ip:   ip,
		Port: port,
		flag: -1,
	}

	conn, err := net.Dial("tcp", fmt.Sprintf("%s:%d", ip, port))
	if err != nil {
		fmt.Println("client server failed --> ", err)
		return nil
	}
	client.conn = conn
	return client
}

var gip string
var gport int

func init() {
	flag.StringVar(&gip, "ip", "127.0.0.1", "设置客户端连接ip")
	flag.IntVar(&gport, "port", 9700, "设置客户端连接端口")
}

func (this *Client) Menu() bool {
	fmt.Println("---------IM-System[start]--------")
	fmt.Println("👥【全服聊天】[1]")
	fmt.Println("👤【私聊】[2]")
	fmt.Println("🧍‍【更改名称】[3]")
	fmt.Println("👀【查看在线用户】[4]")
	fmt.Println("🌲【刷新菜单】[5]")
	fmt.Println("❌【退出】[0]")
	fmt.Println("---------------------------------")
	var flag int
	fmt.Scanln(&flag)
	if flag < 0 || flag > 5 {
		fmt.Println("请输入合法的数值！")
		return false
	}
	this.flag = flag
	return true
}

func (this *Client) Run() {
	for {
		for this.Menu() == false {
		}

		switch this.flag {
		case 1:
			this.PublicChart()
			break
		case 2:
			this.PrivateChart()
			break
		case 3:
			this.ChangeUserName()
			break
		case 4:
			this.ShowOnlineUser()
			break
		case 5:
			break
		case 0:
			this.Exit()
			return
		}
	}
}

// 退出
func (this *Client) Exit() {
	fmt.Println("你是否需要退出？（1-yes, 2-no）")
	this.conn.Close()
	fmt.Println("你已退出连接！")
}

// 全服聊天
func (this *Client) PublicChart() {
	fmt.Println("---------IM-System[全服]--------")
	for {
		fmt.Printf("%s", "请输入内容（输入Q退出）：")
		var msg string
		fmt.Scanln(&msg)
		if msg == "Q" {
			fmt.Println("已退出全服聊天模式")
			return
		}
		this.conn.Write([]byte(msg + "\n"))
	}

}

// 私聊
func (this *Client) PrivateChart() {
	fmt.Println("---------IM-System[私聊]--------")
	fmt.Println("请输入私聊用户民和内容（格式：用户名|内容，输入Q退出）:")
	var msg string
	for {
		fmt.Scanln(&msg)
		if msg == "Q" {
			fmt.Println("已退出私聊模式")
			return
		}
		info := strings.Split(msg, "|")
		user := info[0]
		if user == "" {
			fmt.Println("对端用户名不能为空！")
			return
		}
		content := info[1]
		if content == "" {
			fmt.Println("发送内容不能为空！")
			return
		}
		sendMsg := "to|" + msg + "\n"
		this.conn.Write([]byte(sendMsg))
	}

}

// 查看在线用户
func (this *Client) ShowOnlineUser() {
	this.conn.Write([]byte("who\n"))
}

// 修改用户名
func (this *Client) ChangeUserName() {
	fmt.Println("请输入需要更改到用户名")
	var name string
	fmt.Scanln(&name)
	if name == "" {
		fmt.Println("用户名不能为空！")
		return
	}
	this.conn.Write([]byte("rename|" + name + "\n"))
}

// 处理server数据直接输出到标准输出中
func (this *Client) DetailResponse() {
	io.Copy(os.Stdout, this.conn)
}

func main() {
	// 解析命令行
	flag.Parse()
	client := NewClient(gip, gport)
	if client == nil {
		fmt.Println("❌ 连接服务器失败！")
		return
	}
	go client.DetailResponse()
	fmt.Println("✅ 连接服务器成功！")
	client.Run()
}
